package com.enation.app.javashop.core.system.sendMessage;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dag.eagleshop.core.account.model.dto.base.PageDTO;
import com.dag.eagleshop.core.account.model.dto.withdraw.AuditingDTO;
import com.dag.eagleshop.core.account.model.dto.withdraw.MarkTransferredDTO;
import com.dag.eagleshop.core.account.model.dto.withdraw.QueryWithdrawBillDTO;
import com.dag.eagleshop.core.account.model.enums.TradeChannelEnum;
import com.dag.eagleshop.core.account.service.AccountManager;
import com.enation.app.javashop.core.aftersale.model.dos.RefundDO;
import com.enation.app.javashop.core.aftersale.model.enums.RefundReasonEnum;
import com.enation.app.javashop.core.base.JobAmqpExchange;
import com.enation.app.javashop.core.base.rabbitmq.TimeExecute;
import com.enation.app.javashop.core.distribution.model.dos.DistributionDO;
import com.enation.app.javashop.core.member.model.dos.ConnectDO;
import com.enation.app.javashop.core.member.model.dos.LeaderDO;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.enums.ConnectTypeEnum;
import com.enation.app.javashop.core.member.service.ConnectManager;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.promotion.activitymessage.service.ActivityMessageManager;
import com.enation.app.javashop.core.promotion.pintuan.model.Participant;
import com.enation.app.javashop.core.promotion.pintuan.model.PintuanOrderDetailVo;
import com.enation.app.javashop.core.system.enums.WechatMiniproTemplateTypeEnum;
import com.enation.app.javashop.core.system.model.dto.MiniproMsgDataDTO;
import com.enation.app.javashop.core.system.model.dto.MiniproSendMsgDTO;
import com.enation.app.javashop.core.trade.order.model.vo.OrderDetailVO;
import com.enation.app.javashop.core.trade.order.model.vo.OrderSkuVO;
import com.enation.app.javashop.core.trade.order.service.OrderQueryManager;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.trigger.Interface.TimeTrigger;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
public class WechatSendMessage {

    protected final Log logger = LogFactory.getLog(this.getClass());

    // 延迟发送队列前缀名
    private static final String TRIGGER_PREFIX = "MINIPRO_MESSAGE_";
    @Autowired
    private ConnectManager connectManager;
    @Autowired
    private TimeTrigger timeTrigger;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private AccountManager accountManager;
    @Autowired
    private OrderQueryManager orderQueryManager;
    @Autowired
    private ActivityMessageManager activityMessageManager;
    @Autowired
    private AmqpTemplate amqpTemplate;

    // 封装线程池
    public static final ThreadPoolExecutor WX_MESSAGE_EXECUTOR = new ThreadPoolExecutor(8, 16, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000));


    // 团长审核(分销审核)通知 DistributionDO
    public void sendDistributionMessage(DistributionDO distributionDO) {
        MiniproSendMsgDTO miniproSendMsgDTO;
        Member member = memberManager.getModel(distributionDO.getMemberId());
        ConnectDO connect = connectManager.getConnect(distributionDO.getMemberId(), ConnectTypeEnum.WECHAT.value());
        if (connect == null) {
            logger.warn("小程序消息发送失败，未找到对应的小程序openid");
            return;
        }
        // 封装data参数
        Map<String, Object> dataMap = new HashMap<>();
        // 审核对象
        dataMap.put("thing4", MiniproMsgDataDTO.build(member.getRealName()));
        // 审核状态
        dataMap.put("phrase2", MiniproMsgDataDTO.build(distributionDO.getStatusName()));
        //审核时间
        dataMap.put("date5", MiniproMsgDataDTO.build(DateUtil.toString(distributionDO.getAuditTime(), "yyyy-MM-dd HH:mm:ss")));
        if (2 == distributionDO.getAuditStatus()) {
            //审核说明
            dataMap.put("thing3", MiniproMsgDataDTO.build("你的申请已审核通过，快开始分享赚钱吧~"));
            // 封装消息
            miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.DISTRIBUTION_NOTICE_1,
                    dataMap, "");
        } else {
            //审核说明
            dataMap.put("thing3", MiniproMsgDataDTO.build("你的申请被驳回，原因是：" + distributionDO.getAuditRemark()));
            // 封装消息
            miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.DISTRIBUTION_NOTICE_2,
                    dataMap, "");
        }

        // 延迟发送
        timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());
    }


    // 自提点审核通知
    public void sendPickUpPointMessage(LeaderDO leaderDO) {
        MiniproSendMsgDTO miniproSendMsgDTO;
        ConnectDO connect = connectManager.getConnect(leaderDO.getMemberId(), ConnectTypeEnum.WECHAT.value());
        if (connect == null) {
            logger.warn("小程序消息发送失败，未找到对应的小程序openid");
            return;
        }
        // 封装data参数
        Map<String, Object> dataMap = new HashMap<>();
        //提货地点名称
        dataMap.put("thing1", MiniproMsgDataDTO.build(leaderDO.getSiteName()));
        // 审核时间
        dataMap.put("time2", MiniproMsgDataDTO.build(DateUtil.toString(leaderDO.getAuditTime(), "yyyy-MM-dd HH:mm:ss")));
        //审核结果
        String auditStatusName = leaderDO.getAuditStatus() == 2 ? "审核通过" : "审核拒绝";
        dataMap.put("phrase3", MiniproMsgDataDTO.build(auditStatusName));
        //备注
        if (leaderDO.getAuditStatus() == 2) {
            dataMap.put("thing4", MiniproMsgDataDTO.build("你的申请已审核通过，可以开始赚钱了~"));
            // 封装消息
            miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.PICK_NOTICE_1,
                    dataMap, "");
        } else {
            dataMap.put("thing4", MiniproMsgDataDTO.build("你的申请被驳回，原因是：" + leaderDO.getAuditRemark()));
            // 封装消息
            miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.PICK_NOTICE_2,
                    dataMap, "");
        }
        // 延迟发送
        timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());
    }

    // 账户提现金额 审核通知
    public void sendAuditingMessage(AuditingDTO auditingDTO) {
        WX_MESSAGE_EXECUTOR.execute(() -> {
            MiniproSendMsgDTO miniproSendMsgDTO;
            // 创建查询需要的参数
            QueryWithdrawBillDTO queryWithdrawBillDTO = new QueryWithdrawBillDTO();
            queryWithdrawBillDTO.setId(auditingDTO.getWithdrawBillId());

            List records = accountManager.queryWithdrawList(new PageDTO<>(1, 1, queryWithdrawBillDTO)).getRecords();
            JSONObject json = JSON.parseObject(records.get(0).toString());
            String memberId = json.getString("memberId");
            Member member = memberManager.getMemberByAccountMemberId(memberId);
            ConnectDO connect = connectManager.getConnect(member.getMemberId(), ConnectTypeEnum.WECHAT.value());
            if (connect == null) {
                logger.warn("小程序消息发送失败，未找到对应的小程序openid");
                return;
            }
            String amount = json.getString("amount");
            Date applyTime = json.getDate("applyTime");
            Integer status = json.getInteger("status");
            String statusName = status == 1 ? "审核通过" : "审核拒绝";
            Date inspectTime = json.getDate("inspectTime");
            String inspectRemark = json.getString("inspectRemark");
            // 封装data参数
            Map<String, Object> dataMap = new HashMap<>();
            //提现金额
            dataMap.put("amount1", MiniproMsgDataDTO.build(amount));
            // 申请时间
            dataMap.put("date4", MiniproMsgDataDTO.build(DateUtil.toString(applyTime, "yyyy-MM-dd HH:mm:ss")));
            //审核结果
            dataMap.put("phrase2", MiniproMsgDataDTO.build(statusName));
            //审核时间
            dataMap.put("date3", MiniproMsgDataDTO.build(DateUtil.toString(inspectTime, "yyyy-MM-dd HH:mm:ss")));

            if (status == 1) {
                //注意事项
                dataMap.put("thing5", MiniproMsgDataDTO.build("1-3个工作日内打款，请留意→"));
                // 封装消息
                miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.WITHDRAWAL_NOTICE,
                        dataMap, "");
            } else {
                //注意事项
                dataMap.put("thing5", MiniproMsgDataDTO.build("提现审核不通过，原因" + inspectRemark));
                // 封装消息
                miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.WITHDRAWAL_NOTICE,
                        dataMap, "");
            }
            // 延迟发送
            timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());

        });
    }


    // 账户提现金额 结果通知
    public void sendMarkTransferMessage(MarkTransferredDTO markTransferredDTO) {
        WX_MESSAGE_EXECUTOR.execute(() -> {
            MiniproSendMsgDTO miniproSendMsgDTO;
            // 创建查询需要的参数
            QueryWithdrawBillDTO queryWithdrawBillDTO = new QueryWithdrawBillDTO();
            queryWithdrawBillDTO.setId(markTransferredDTO.getWithdrawBillId());
            List records = accountManager.queryWithdrawList(new PageDTO<>(1, 1, queryWithdrawBillDTO)).getRecords();
            JSONObject json = JSON.parseObject(records.get(0).toString());
            // 账户虚拟账号
            String memberId = json.getString("memberId");
            Member member = memberManager.getMemberByAccountMemberId(memberId);
            ConnectDO connect = connectManager.getConnect(member.getMemberId(), ConnectTypeEnum.WECHAT.value());
            if (connect == null) {
                logger.warn("小程序消息发送失败，未找到对应的小程序openid");
                return;
            }
            String amount = json.getString("amount");
            Date applyTime = json.getDate("applyTime");
            Integer status = json.getInteger("status");
            String statusName = status == 3 ? "打款成功" : "打款失败";
            String memberName = json.getString("memberName");
            //截去用户名前缀 【用户】【团长】
            memberName = memberName.substring(memberName.indexOf("】") + 1);
            String transferRemark = StringUtil.notEmpty(markTransferredDTO.getTransferRemark()) ? markTransferredDTO.getTransferRemark() : json.getString("transferRemark");
            //提现渠道，1银行卡 2支付宝 3微信
            Integer withdrawChannel = json.getInteger("withdrawChannel");

            // 封装data参数
            Map<String, Object> dataMap = new HashMap<>();
            //提现金额
            dataMap.put("amount1", MiniproMsgDataDTO.build(amount));
            // 提现人
            dataMap.put("thing5", MiniproMsgDataDTO.build(memberName));
            //申请时间
            dataMap.put("date3", MiniproMsgDataDTO.build(DateUtil.toString(applyTime, "yyyy-MM-dd HH:mm:ss")));
            //提现结果
            dataMap.put("phrase2", MiniproMsgDataDTO.build(statusName));

            if (status == 3) {
                //温馨提示
                if (withdrawChannel == TradeChannelEnum.WECHAT.getIndex()) {
                    // 微信
                    dataMap.put("thing4", MiniproMsgDataDTO.build("提现成功，已转入微信钱包，请查收→"));
                } else {
                    // 支付宝和银行卡
                    dataMap.put("thing4", MiniproMsgDataDTO.build("提现成功，1-7个工作日到账，请留意→"));
                }

                // 封装消息
                miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.WITHRESULT_NOTICE,
                        dataMap, "");
            } else {
                //温馨提示
                dataMap.put("thing4", MiniproMsgDataDTO.build(transferRemark));
                // 封装消息
                miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.WITHRESULT_NOTICE,
                        dataMap, "");
            }
            // 延迟发送
            timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());

        });
    }

    // 多退 退款提醒
    public void sendRefundMessage(RefundDO refundDO) {
        MiniproSendMsgDTO miniproSendMsgDTO;
        ConnectDO connect = connectManager.getConnect(refundDO.getMemberId(), ConnectTypeEnum.WECHAT.value());
        if (connect == null) {
            logger.warn("小程序消息发送失败，未找到对应的小程序openid");
            return;
        }
        OrderDetailVO orderDetailVO = orderQueryManager.getModel(refundDO.getOrderSn(), null);
        List<OrderSkuVO> orderSkuList = orderDetailVO.getOrderSkuList();
        String goodsName = null;
        if (orderSkuList != null && orderSkuList.size() > 0) {
            if (orderSkuList.size() > 1) {
                goodsName = orderSkuList.get(0).getName() + "等";
            } else {
                goodsName = orderSkuList.get(0).getName();
            }
        }
        // 封装data参数
        Map<String, Object> dataMap = new HashMap<>();
        //订单号
        dataMap.put("character_string4", MiniproMsgDataDTO.build(refundDO.getOrderSn()));
        // 商品名称
        dataMap.put("thing5", MiniproMsgDataDTO.build(goodsName));
        //退款金额
        dataMap.put("amount1", MiniproMsgDataDTO.build(refundDO.getRefundPrice().toString() + "元"));
        //退款时间 nullpointException
        dataMap.put("time2", MiniproMsgDataDTO.build(DateUtil.toString(refundDO.getRefundTime(), "yyyy-MM-dd HH:mm:ss")));
        //退款原因
        dataMap.put("thing6", MiniproMsgDataDTO.build("订单" + RefundReasonEnum.valueOf(refundDO.getRefundReason()).description() + "产生退款，请查看→"));
        // 封装消息
        miniproSendMsgDTO = new MiniproSendMsgDTO(connect.getOpenId(), WechatMiniproTemplateTypeEnum.REFUND_NOTICE,
                dataMap, "");
        // 延迟发送
        timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());
    }

    // 拼团结果通知
    public void sendGroupWorkMessage(PintuanOrderDetailVo pintuanOrderDetailVo, String openId, boolean pintuanStatus, Integer sendMemberId) {
        MiniproSendMsgDTO miniproSendMsgDTO;

        if (StringUtil.isEmpty(openId)) {
            logger.error("小程序消息发送失败，未找到对应的小程序openid");
            return;
        }
        // 封装data参数
        Map<String, Object> dataMap = new HashMap<>();
        // 商品名称
        dataMap.put("thing1", MiniproMsgDataDTO.build(pintuanOrderDetailVo.getGoodsName()));
        //  拼团结果
        String pintuanResult = pintuanStatus ? "拼团成功": "拼团失败";
        dataMap.put("thing2", MiniproMsgDataDTO.build(pintuanResult));
        // 拼团人数
        Integer requiredNum = pintuanOrderDetailVo.getRequiredNum();
        dataMap.put("thing3", MiniproMsgDataDTO.build(requiredNum.toString()));
        // 拼团价格
        dataMap.put("amount4", MiniproMsgDataDTO.build(pintuanOrderDetailVo.getSalesPrice().toString()));
        // 拼团人昵称
        List<Participant> participants = pintuanOrderDetailVo.getParticipants();

        String content = "可再次发起拼单或者和别人一起拼哦~";
        //温馨提示
        if (pintuanStatus) {
            // 获取一个其他参团人的名字
            String nickName = "";
            for (Participant participant : participants) {
                if (sendMemberId.equals(participant.getId())) {
                    continue;
                }
                nickName = participant.getName();
                break;
            }
            content = "恭喜你和" + nickName + (requiredNum == 2 ? "" : "等") + requiredNum + "人拼团成功";
        }
        dataMap.put("thing5", MiniproMsgDataDTO.build(content));
        // 封装消息
        miniproSendMsgDTO = new MiniproSendMsgDTO(openId, WechatMiniproTemplateTypeEnum.GROUP_WORK_NOTICE,
                dataMap, "");
        // 延迟发送
        timeTrigger.add(TimeExecute.MINIPRO_MESSAGE_EXECUTER, miniproSendMsgDTO, DateUtil.getDateline(), TRIGGER_PREFIX + DateUtil.getDateline());
    }

}
